﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq.Expressions;
using Loki.Commands;

namespace Loki.Utils
{
    /// <summary>
    /// Interface for change manager service.
    /// </summary>
    public interface IEventService : IService
    {
        /// <summary>
        /// Registers the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <typeparam name="TListener">The type of the listener.</typeparam>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Property">The property.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_PropertyChangedCallback">The property changed callback.</param>
        void RegisterPropertyChanged<TSource, TListener>(TSource P_Source, Expression<Func<TSource, object>> P_Property, TListener P_Listener, Action<TListener, object, PropertyChangedEventArgs> P_PropertyChangedCallback) where TSource : INotifyPropertyChanged;

        /// <summary>
        /// Registers the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <typeparam name="TSource">The type of the listener.</typeparam>
        /// <typeparam name="TListener">The type of the source.</typeparam>
        /// <param name="P_Source">The property.></param>
        /// <param name="P_PropertyName">The property name.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_PropertyChangedCallback">The property changed callback.</param>
        void RegisterPropertyChanged<TSource, TListener>(TSource P_Source, string P_PropertyName, TListener P_Listener, Action<TListener, object, PropertyChangedEventArgs> P_PropertyChangedCallback) where TSource : INotifyPropertyChanged;

        /// <summary>
        /// Unregisters the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_PropertyName">Name of the property.</param>
        /// <param name="P_Listener">The event listener.</param>
        void UnregisterPropertyChanged<TSource>(TSource P_Source, Expression<Func<TSource, object>> P_Property, object P_Listener) where TSource : INotifyPropertyChanged;

        /// <summary>
        /// Unregisters the event source.
        /// </summary>
        /// <param name="source">The event source.</param>
        void UnregisterPropertyChangedSource<TSource>(TSource source) where TSource : INotifyPropertyChanged;

        /// <summary>
        /// Registers the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <typeparam name="TListener">The type of the listener.</typeparam>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_Callback">The callback.</param>
        void RegisterStateChanged<TListener>(ICentralizedChangeTracking P_Source, TListener P_Listener, Action<TListener, object, EventArgs> P_Callback);

        /// <summary>
        /// Unregisters the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        void UnregisterStateChanged(ICentralizedChangeTracking P_Source, object P_Listener);

        /// <summary>
        /// Unregisters the event source.
        /// </summary>
        /// <param name="source">The event source.</param>
        void UnregisterStateChangedSource(ICentralizedChangeTracking source);

        /// <summary>
        /// Registers the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <typeparam name="TListener">The type of the listener.</typeparam>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_Callback">The callback.</param>
        void RegisterChanged<TListener>(INotifyPropertyChanged P_Source, TListener P_Listener, Action<TListener, object, PropertyChangedEventArgs> P_Callback);

        /// <summary>
        /// Unregisters the specified INotifyPropertyChanged handler.
        /// </summary>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        void UnregisterChanged(INotifyPropertyChanged P_Source, object P_Listener);

        /// <summary>
        /// Unregisters the event source.
        /// </summary>
        /// <param name="source">The event source.</param>
        void UnregisterChangedSource(INotifyPropertyChanged source);

        /// <summary>
        /// Registers the specified INotifyCollectionChanged handler.
        /// </summary>
        /// <typeparam name="TListener">The type of the listener.</typeparam>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_Callback">The callback.</param>
        void RegisterCollectionChanged<TListener>(INotifyCollectionChanged P_Source, TListener P_Listener, Action<TListener, object, NotifyCollectionChangedEventArgs> P_Callback);

        /// <summary>
        /// Unregisters the specified INotifyCollectionChanged handler.
        /// </summary>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        void UnregisterCollectionChanged(INotifyCollectionChanged P_Source, object P_Listener);

        /// <summary>
        /// Unregisters the event source.
        /// </summary>
        /// <param name="source">The event source.</param>
        void UnregisterCollectionChangedSource(INotifyCollectionChanged source);

        /// <summary>
        /// Registers the specified INotifyCanExecuteChanged handler.
        /// </summary>
        /// <typeparam name="TListener">The type of the listener.</typeparam>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        /// <param name="P_Callback">The callback.</param>
        void RegisterCanExecuteChanged<TListener>(INotifyCanExecuteChanged P_Source, TListener P_Listener, Action<TListener, object, EventArgs> P_Callback);

        /// <summary>
        /// Unregisters the specified INotifyCollectionChanged handler.
        /// </summary>
        /// <param name="P_Source">The event source.</param>
        /// <param name="P_Listener">The event listener.</param>
        void UnregisterCanExecuteChanged(INotifyCanExecuteChanged P_Source, object P_Listener);

        /// <summary>
        /// Unregisters the event source.
        /// </summary>
        /// <param name="source">The event source.</param>
        void UnregisterCanExecuteChangedSource(INotifyCanExecuteChanged source);

        /// <summary>
        /// Removes the collected entries.
        /// </summary>
        void RemoveCollectedEntries();
    }
}
